package br.pb.sistcomp.controller;

import br.pb.sistcomp.dao.VendaDao;
import br.pb.sistcomp.dao.VendaDaoImpl;
import br.pb.sistcomp.entity.Venda;
import br.pb.sistcomp.exception.ErroAoRemoverException;
import br.pb.sistcomp.exception.ErroAoSalvarException;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

/**
 * Class that represents an entity in the system
 *
 * @author jefferson Bello, Jefferson.bello@dce.ufpb.br
 * @version 1.1
 *
 * Copyright (C) 2011 SistComp.
 */
@ManagedBean
@RequestScoped
public class VendaController {

    // Atributos
    private VendaDao vendaDao;
    private List<Venda> listaDeVendas;
    private DataModel modelSales;
    // Objeto da classe venda
    private Venda selectSale;
    // Variável qual guarda o valor original da venda, sem acrescimos ou descontos
    private float valorInicialDaVenda = 0;
    // Váriavel qual guarda a quantidade de parcelas escolhidas para o pagamento da compra usando cartão de crédito
    private int qtdeParcelasCartao = 1;
    // Váriavel responsável em guardar o valor de cada parcela de uma compra, onde o cliente escolheu a forma de pagamento sendo cartão de crédito.
    private float valorParcelaCartao = 0;
    // Váriavel responsável em guardar o valor do desconto oferecido a ele, por uma compra com a forma de pagamento A vista.
    private double valorDoDescontoAVista = 0;

    /**
     * Construtor da classe Venda Controller, responsável em instanciar os objetos das classes venda e venda DAO.
     */
    public VendaController() {
        vendaDao = new VendaDaoImpl();
        selectSale = new Venda();
    }

    /**
     *  Método responsável em verificar qual a forma de pagamento o cliente prefere para finalizar sua compra, considerando a forma escolhida, direciona o cliente a pagina correta..
     * @param tipoDePagamento, do tipo String, contem a informações do pagamento escolhido pelo cliente.
     * @return retorna uma String qual contem o nome da página qual o cliente será redicionado.
     */
    public String beginSale() {
        if (selectSale.getFormaDePagamento().equalsIgnoreCase("boleto")) {
            this.selectSale.setFormaDePagamento("boleto");
            // Guarda em uma variavel o valor original da venda, sem nenhum acrescimo ou desconto
            this.valorInicialDaVenda = selectSale.getValor();
            // Como a opção escolhida foi boleto bancário, será adcionado 3 reais ( Valor padrão ) ao valor final da venda, tarifa pela confecção do boleto.
            selectSale.setValor(selectSale.getValor() + 3);
            return "boleto";
        } else if (selectSale.getFormaDePagamento().equalsIgnoreCase("cartaoDeCredito")) {
            // Caso a opção escolhida for cartão de crédito, o cliente será redirecionado para outra página, onde o mesmo escolherá¡ a quantidade das parcelas para o pagamento da conta.
            this.selectSale.setFormaDePagamento("cartaoDeCredito");
            return "cartaoDeCredito";
        } else {
            this.selectSale.setFormaDePagamento("aVista");
            this.selectSale.setValor(selectSale.getValor());
            // Caso a forma de pagamento escolhida for a vista, será subtraido 5% do valor da compra ( desconto padrão )
            this.valorInicialDaVenda = selectSale.getValor();
            selectSale.setValor(selectSale.getValor() - (selectSale.getValor() * 5 / 100));
            // função que calcula o desconto da compra do cliente, considerando o valor pago pela mesma.
            descontoAVista();
            return "aVista";
        }
    }



    /**
     * Método responsável em guardar o conteudo da venda finalizada no banco de dados
     * @param selectSale, do tipo Venda, representa toda informação necessária do objeto manipulado.
     * @return retorna uma String qual encaminhará¡ o cliente a página de listar produtos.
     */
    public String finishingSale() {
        try {
            vendaDao.cadastrarVenda(this.selectSale);
        } catch (ErroAoSalvarException e) {
            e.getMessage();
        } finally {
            listaDeVendas = null;
            return "listTheProducts";
        }
    }

    /**
     * Método responsável em informar o valor de cada parcela, caso o cliente escolha dividir o valor da sua compra utilizando a forma de pagamento cartão de crédito
     * @param quantidadeParcelas, do tipo inteiro, informa quantas prestações o cliente deseja que seja dividido o valor final de sua compra.
     */
    public String valorCartao() {
        this.valorInicialDaVenda = selectSale.getValor();
        this.valorParcelaCartao = (selectSale.getValor() / this.qtdeParcelasCartao);
        return "cartaoDeCredito_2";
    }

    /**
     * Método privado responsável em calcular o desconto da compra com pagamento a vista.
     */
    private void descontoAVista() {
        this.valorDoDescontoAVista = this.valorInicialDaVenda * 0.05;
    }

    /**
     * Método responsável em listar as vendas considerando sua forma de pagamento. ( A vista, boleto ou a cartao )
     * @param tipo String, informação qual representa o tipo de pagamento escolhido.
     * @return Uma String contendo o nome da pagina de redirecionamento
     */
    //public String listarVendas(String formaDePagamento) {
    public String listarVendas() {
        //modelSales = carregarVendas(formaDePagamento);
        modelSales = carregarVenda();
        return "listTheProducts";
    }

    /**
     * MÃ©todo com finalidade de carregar a lista de vendas presente no banco de dados.
     * @param formaDePagamento, do tipo String, informação qual representa o tipo de pagamento escolhido.
     * @return um Objeto do tipo DataModel, representa a lista de vendas realizada, considerando a forma de pagamento passada por parametro.
     */
    // private DataModel carregarVendas(String formaDePagamento) {
   // private DataModel carregarVendas() {
        // return new ListDataModel(vendaDao.listarVendas(formaDePagamento));
     //   return new ListDataModel(vendaDao.listarVendas());
    //}

        public DataModel carregarVenda() {
        modelSales = new ListDataModel(vendaDao.listarVendas());
        return modelSales;


    }

    /**
     * Método responsável em remover uma venda do banco de dados.
     * @return Uma String contendo o nome da página de redirecionamento.
     */
    public String excluir() {
        try {
            Venda venda = (Venda) modelSales.getRowData();
            vendaDao.removerVenda(venda);
            modelSales = carregarVenda();
        } catch (ErroAoRemoverException e) {
            e.getMessage();
        } finally {
            return "listTheProducts";
        }
        // modelSales = carregarVendas(venda.getFormaDePagamento());
    }

    // Métodos de acesso aos atributos na classe.
    public List<Venda> getListaDeVendas() {
        return vendaDao.listarVendas();
    }

    public DataModel getModelSales() {
        return modelSales;
    }

    public Venda getSelectSale() {
        return selectSale;
    }

    public int getQuantidadeParcela() {
        return qtdeParcelasCartao;
    }

    public VendaDao getVendaDao() {
        return vendaDao;
    }

    public float getValorParcelaCartao() {
        return (selectSale.getValor() / this.qtdeParcelasCartao);
    }

    public void setQuantidadeParcela(int quantidadeParcela) {
        this.qtdeParcelasCartao = quantidadeParcela;
    }

    public void setSelectSale(Venda selectSale) {
        this.selectSale = selectSale;
    }

    public void setValorParcelaCartao(float valorParcelaCartao) {
        this.valorParcelaCartao = valorParcelaCartao;
    }

    public void setVendaDao(VendaDao vendaDao) {
        this.vendaDao = vendaDao;
    }

    public float getValorInicialDaVenda() {
        return valorInicialDaVenda;
    }

    public void setValorInicialDaVenda(float valorInicialDaVenda) {
        this.valorInicialDaVenda = valorInicialDaVenda;
    }

    public double getValorDoDescontoAVista() {
        return valorDoDescontoAVista;
    }

    public void setValorDoDescontoAVista(double valorDoDescontoAVista) {
        this.valorDoDescontoAVista = valorDoDescontoAVista;
    }
}
